home *** CD-ROM | disk | FTP | other *** search
/ Giga Games 1 / Giga Games.iso / net / go / prog / tinygo2.sh < prev    next >
Encoding:
Linux/UNIX/POSIX Shell Script  |  1993-06-20  |  23.6 KB  |  986 lines

  1. #! /bin/sh
  2. # This is a shell archive, meaning:
  3. # 1. Remove everything above the #! /bin/sh line.
  4. # 2. Save the resulting text in a file.
  5. # 3. Execute the file with /bin/sh (not csh) to create the files:
  6. #    Makefile
  7. #    README
  8. #    basics.c
  9. #    godefs.h
  10. #    set.c
  11. #    set.h
  12. #    test.c
  13. # This archive created: Thu Dec 20 18:55:52 1990
  14. export PATH; PATH=/bin:$PATH
  15. echo shar: extracting "'Makefile'" '(100 characters)'
  16. if test -f 'Makefile'
  17. then
  18.     echo shar: will not over-write existing file "'Makefile'"
  19. else
  20. sed 's/^X//' << \SHAR_EOF > 'Makefile'
  21. XCFLAGS = -g
  22. XCC=gcc
  23. X
  24. XOBJS = basics.o set.o test.o
  25. X
  26. Xgo: $(OBJS)
  27. X    gcc -o go $(OBJS) -lcurses -ltermcap
  28. SHAR_EOF
  29. if test 100 -ne "`wc -c < 'Makefile'`"
  30. then
  31.     echo shar: error transmitting "'Makefile'" '(should have been 100 characters)'
  32. fi
  33. fi # end of overwriting check
  34. echo shar: extracting "'README'" '(1262 characters)'
  35. if test -f 'README'
  36. then
  37.     echo shar: will not over-write existing file "'README'"
  38. else
  39. sed 's/^X//' << \SHAR_EOF > 'README'
  40. XThese files forms a (very basic) part of a computer go players perseption.
  41. XThe functions and structures implements the go board while keeping track
  42. Xof rules (though with a simple ko-rule), block (sometimes called strings
  43. Xor groups) and with the possibility of undoing any number of moves.
  44. XIt should be possible (so says B. Wilcox) to build a tactian with
  45. Xjust this simple view of the board.
  46. X
  47. XThe representation of blocks is designed for incremental update. The
  48. Xreason for the possibly inactive status of some block is easy undo.
  49. X
  50. XAll this code is in an early state, but i wanted to get it out while
  51. Xthe water was boiling in rec.games.go. I have implemented David Bensons
  52. Xunconditional life algorithm and is halfway though with a FAST pattern-
  53. Xmatcher (actually, I didn't think anything good of pattern matching,
  54. Xbut a friend of mine and myself happend to fall over a very good idea).
  55. X
  56. XIncluded just for fun is a test program which borrows much from Jeff
  57. XRosenfeld (thank you, jeff!).
  58. X
  59. XIt is hereby placed in the public domain, Tommy Thorn Dec 1990
  60. X-----------------------------------------------------------------------
  61. XTommy Thorn                       email: tthorn@daimi.aau.dk
  62. XComputer Science Department       I SPEAK FOR MYSELF!
  63. XAarhus University 
  64. XDENMARK
  65. SHAR_EOF
  66. if test 1262 -ne "`wc -c < 'README'`"
  67. then
  68.     echo shar: error transmitting "'README'" '(should have been 1262 characters)'
  69. fi
  70. fi # end of overwriting check
  71. echo shar: extracting "'basics.c'" '(9845 characters)'
  72. if test -f 'basics.c'
  73. then
  74.     echo shar: will not over-write existing file "'basics.c'"
  75. else
  76. sed 's/^X//' << \SHAR_EOF > 'basics.c'
  77. X/*
  78. X * BASICS -- basic view of the go board
  79. X *
  80. X * created 7/12-90
  81. X *
  82. X * Tommy Thorn                       email: tthorn@daimi.aau.dk
  83. X * Computer Science Department       I SPEAK FOR MYSELF!
  84. X * Aarhus University 
  85. X * DENMARK
  86. X */
  87. X
  88. X#include <stdio.h>
  89. X#include "godefs.h"
  90. X
  91. Xint dir[9][5]; /* dir[dirindex[s]] gives a zero terminated list */
  92. X
  93. Xblock *newblock(basicview *);
  94. X
  95. X#define push(bv, i) bv->undostack[bv->undosp++] = i
  96. X#define pop(bv) bv->undostack[--bv->undosp]
  97. X#define top(bv) bv->undostack[bv->undosp-1]
  98. X
  99. Xvoid init(basicview *bv, int w)
  100. X{
  101. X    int i, *n, k;
  102. X    
  103. X    /* initialise dir, nothing to do with bv */
  104. X    
  105. X    for (i = 0; i < 9; ++i) {
  106. X        n = dir[i];
  107. X        if (i >= 3) *n++ = -w;
  108. X        if (i % 3 != 2) *n++ = 1;
  109. X        if (i <= 5) *n++ = w;
  110. X        if (i % 3 != 0) *n++ = -1;
  111. X        *n = 0;
  112. X    }
  113. X    
  114. X    bv->w = w;
  115. X    bv->max = w*w-1;
  116. X    bv->turn = 1;
  117. X    bv->to_play = BLACK;
  118. X    bv->passes = 0;
  119. X    bv->ko_spot = -1;
  120. X    bv->next_free_id = 0;
  121. X    
  122. X    for (i = w*w-1; 0 <= i; --i) {
  123. X        bv->dirindex[i] = 4;
  124. X        bv->color[i] = EMPTY;
  125. X    bv->block_id[i] = -1;
  126. X    }
  127. X    
  128. X    for (i = 1, k = (w-1)*w+1; i < w-1; ++i, ++k)
  129. X      bv->dirindex[i] = 1, bv->dirindex[k] = 7;
  130. X    for (i = 1; i < w-1; ++i)
  131. X      bv->dirindex[i*w] = 3, bv->dirindex[i*w+w-1] = 5;
  132. X    bv->dirindex[0] = 0; bv->dirindex[w-1] = 2;
  133. X    bv->dirindex[w*w-w] = 6; bv->dirindex[w*w-1] = 8;
  134. X    bv->undosp = 0;
  135. X}
  136. X
  137. Xblock *newblock(basicview *bv)
  138. X{
  139. X    block *bp;
  140. X    
  141. X    bp = (block *) malloc(sizeof(block));
  142. X    memset(bp, 0, sizeof(block));
  143. X    bp->id = bv->next_free_id;
  144. X    bv->block_ref[bv->next_free_id++] = bp;
  145. X    return bp;
  146. X}
  147. X
  148. Xrecycleblock(basicview *bv, block *bp)
  149. X{
  150. X    if (bp->id != bv->next_free_id-1)
  151. X      fprintf(stderr, "What!\n"), exit(1);
  152. X    
  153. X    bv->next_free_id--;
  154. X    bv->block_ref[bp->id] = NULL;
  155. X    free(bp);
  156. X}
  157. X
  158. Xint moveis(basicview *bv, int s)
  159. X{
  160. X    int n, friend, connecting, nlibs, captures;
  161. X    
  162. X    if (s == -1)
  163. X      return MOVEIS_PASS;
  164. X    if (s < 0 || s > bv->max)
  165. X      return ERR_OUT_OF_BOARD;
  166. X    if (bv->color[s] != EMPTY)
  167. X      return ERR_OCCUPIED;
  168. X    if (s == bv->ko_spot)
  169. X      return ERR_KO_VIOLATION;
  170. X    if (bv->passes == 2)
  171. X      return ERR_GAME_OVER;
  172. X    
  173. X    nlibs = connecting = captures = 0;
  174. X    friend = -1;
  175. X    {
  176. X    foreachneighbor(bv, s, n)
  177. X      if (bv->color[n] == EMPTY)
  178. X        ++nlibs;
  179. X      else if (bv->color[n] == bv->to_play) {
  180. X          if (friend != -1 && friend != bv->block_id[n])
  181. X        connecting = YES;
  182. X          friend = bv->block_id[n];
  183. X          nlibs += bv->block_ref[friend]->nlibs - 1;
  184. X      }
  185. X      else if (bv->block_ref[bv->block_id[n]]->nlibs == 1)
  186. X        captures = MOVE_CAPTURES;
  187. X    }
  188. X    
  189. X    /* note: nlibs may not be the correct number of liberties for the
  190. X       resulting block, but it is zero in case of suicide */
  191. X    if (nlibs == 0 && !captures)
  192. X      return ERR_SUICIDE;
  193. X    if (friend == -1)
  194. X      return MOVEIS_NEW + captures;
  195. X    if (connecting)
  196. X      return MOVEIS_CONNECT + captures;
  197. X    else
  198. X      return MOVEIS_EXTEND + captures;
  199. X}
  200. X
  201. Xblock *block_simple(basicview *bv, int s, int movetype)
  202. X{
  203. X    block *bp;
  204. X    int n;
  205. X    
  206. X    bv->color[s] = bv->to_play;
  207. X    if (movetype == MOVEIS_NEW || movetype == MOVEIS_NEW+MOVE_CAPTURES)
  208. X      bp = newblock(bv), bp->color = bv->to_play;
  209. X    else {
  210. X    foreachneighbor(bv, s, n)
  211. X      if (bv->color[n] == bv->to_play) {
  212. X          bp = bv->block_ref[bv->block_id[n]];
  213. X          break;
  214. X      }
  215. X    }
  216. X    setadd(bp->stones, s);
  217. X    if (movetype == MOVEIS_EXTEND || movetype == MOVEIS_EXTEND+MOVE_CAPTURES)
  218. X      setremove(bp->libs, s), --bp->nlibs;
  219. X    bv->block_id[s] = bp->id;
  220. X    {
  221. X    foreachneighbor(bv, s, n)
  222. X      if (bv->color[n] == EMPTY && !setisin(bp->libs, n))
  223. X        setadd(bp->libs, n), ++bp->nlibs;
  224. X    } 
  225. X    return bp;
  226. X}
  227. X
  228. Xblock *block_connect(basicview *bv, int s)
  229. X{
  230. X    block *bp, *nbp;
  231. X    int n;
  232. X    
  233. X    bv->color[s] = bv->to_play;
  234. X    bp = newblock(bv);
  235. X    bp->color = bv->to_play;
  236. X    setadd(bp->stones, s);
  237. X    {
  238. X    foreachneighbor(bv, s, n)
  239. X      if (bv->color[n] == EMPTY)
  240. X        setadd(bp->libs, n);
  241. X      else if (bv->color[n] == bv->to_play && !setisin(bp->stones, n)) {
  242. X          nbp = bv->block_ref[bv->block_id[n]];
  243. X          
  244. X          setunion(bp->stones, bp->stones, nbp->stones);
  245. X          setunion(bp->libs, bp->libs, nbp->libs);
  246. X          nbp->status = BLOCK_INACTIVE;
  247. X          push(bv, nbp->id); /* push info for easy undo of connect */
  248. X      }
  249. X    } 
  250. X    setremove(bp->libs, s);
  251. X    bp->nlibs = setsize(bp->libs);
  252. X    {
  253. X    setforeach(bp->stones, n)
  254. X      bv->block_id[n] = bp->id;
  255. X    } 
  256. X    return bp;
  257. X}
  258. X
  259. Xint play(basicview *bv, int s)
  260. X{
  261. X    block *nbp;
  262. X    int movetype, n, old_undosp = bv->undosp;
  263. X    int old_ko = bv->ko_spot;
  264. X    
  265. X    switch (movetype = moveis(bv, s)) {
  266. X      case ERR_OUT_OF_BOARD:
  267. X      case ERR_OCCUPIED:
  268. X      case ERR_KO_VIOLATION:
  269. X      case ERR_SUICIDE:
  270. X      case ERR_GAME_OVER:
  271. X    return movetype;
  272. X      case MOVEIS_PASS:
  273. X    bv->passes++;
  274. X    bv->to_play = OTHER(bv->to_play);
  275. X    bv->turn++;
  276. X    push(bv, bv->ko_spot);
  277. X    push(bv, MOVEIS_PASS);
  278. X    bv->ko_spot = -1;
  279. X    
  280. X    return MOVEIS_PASS;
  281. X    
  282. X    /* in the case of a good move, first update color, stones and libs */
  283. X      case MOVEIS_NEW:
  284. X      case MOVEIS_EXTEND:
  285. X      case MOVEIS_NEW+MOVE_CAPTURES:
  286. X      case MOVEIS_EXTEND+MOVE_CAPTURES:
  287. X    block_simple(bv, s, movetype);
  288. X    break;
  289. X      case MOVEIS_CONNECT:
  290. X      case MOVEIS_CONNECT+MOVE_CAPTURES:
  291. X    block_connect(bv, s);
  292. X    break;
  293. X      default:
  294. X    fprintf(stderr, "moveis returned %d in play\n", movetype), exit(1);
  295. X    }
  296. X    
  297. X    /* now update my neighbors liberties and possibly capture them */
  298. X    {
  299. X    foreachneighbor(bv, s, n)
  300. X      if (bv->color[n] == OTHER(bv->to_play)) {
  301. X          nbp = bv->block_ref[bv->block_id[n]];
  302. X          if (setisin(nbp->libs, s)) {
  303. X          setremove(nbp->libs, s);
  304. X          --nbp->nlibs;
  305. X          if (nbp->nlibs == 0) {
  306. X              capture_block(bv, nbp);
  307. X              push(bv, nbp->id); /*push capturing info for easy undo*/
  308. X              if (setsize(nbp->stones) == 1)
  309. X            bv->ko_spot = n; /* possibly a ko spot */
  310. X          }
  311. X          }
  312. X      }
  313. X    } 
  314. X    
  315. X    if (bv->block_ref[bv->block_id[s]]->nlibs != 1
  316. X    || !(movetype & MOVE_CAPTURES))
  317. X      bv->ko_spot = -1;
  318. X    bv->turn++;
  319. X    bv->to_play = OTHER(bv->to_play);
  320. X    bv->passes = 0;
  321. X    push(bv, old_ko);
  322. X    n = bv->undosp - 1 - old_undosp;
  323. X    push(bv, movetype + 8*n + 64 * s);
  324. X    
  325. X    return movetype;
  326. X}
  327. X
  328. X/* run through every stone of the block, setting block_id[i] = -1
  329. X *      for each neighbor if enemy and hasn't i as liberty
  330. X *         get i as liberty and update nlibs
  331. X */
  332. X
  333. Xcapture_block(basicview *bv, block *bp)
  334. X{
  335. X    int n, i, enemy = OTHER(bp->color);
  336. X    block *nbp;
  337. X    
  338. X    bp->status = BLOCK_CAPTURED;
  339. X    {
  340. X    setforeach(bp->stones, i) {
  341. X        bv->block_id[i] = -1;
  342. X        bv->color[i] = EMPTY;
  343. X        {
  344. X        foreachneighbor(bv, i, n) {
  345. X            if (bv->color[n] == enemy) {
  346. X            nbp = bv->block_ref[bv->block_id[n]];
  347. X            if (!setisin(nbp->libs, i)) {
  348. X                setadd(nbp->libs, i);
  349. X                ++nbp->nlibs;
  350. X            }
  351. X            }
  352. X        }
  353. X        } 
  354. X    } 
  355. X    }
  356. X
  357. X}
  358. X
  359. X/* run through every stone of the block, setting block_id[i] = bp->id
  360. X *    for each neighbor if enemy and has i as lib
  361. X *         remove i as lib ..
  362. X */
  363. X
  364. Xuncapture_block(basicview *bv, block *bp)
  365. X{
  366. X    int n, i, enemy = OTHER(bp->color);
  367. X    block *nbp;
  368. X    
  369. X    bp->status = BLOCK_ACTIVE;
  370. X    {
  371. X    setforeach(bp->stones, i) {
  372. X        
  373. X        bv->block_id[i] = bp->id;
  374. X        bv->color[i] = bp->color;
  375. X        {
  376. X        foreachneighbor(bv, i, n)
  377. X          if (bv->color[n] == enemy) {
  378. X              nbp = bv->block_ref[bv->block_id[n]];
  379. X              if (setisin(nbp->libs, i)) {
  380. X              setremove(nbp->libs, i);
  381. X              --nbp->nlibs;
  382. X              }
  383. X          }
  384. X        } 
  385. X    } 
  386. X    }
  387. X}
  388. X
  389. Xundo_simple(basicview *bv, int s, int movetype, block *bp)
  390. X{
  391. X    int n, nn;
  392. X    
  393. X    bv->color[s] = EMPTY;
  394. X    bv->block_id[s] = -1;
  395. X    if (movetype == MOVEIS_EXTEND || movetype == MOVEIS_EXTEND+MOVE_CAPTURES) {
  396. X    foreachneighbor(bv, s, n)
  397. X      if (bv->color[n] == bv->to_play) {
  398. X          bp = bv->block_ref[bv->block_id[n]];
  399. X          break;
  400. X      }
  401. X    
  402. X    setremove(bp->stones, s);
  403. X    setadd(bp->libs, s), ++bp->nlibs;
  404. X    {
  405. X        foreachneighbor(bv, s, n)
  406. X          if (bv->color[n] == EMPTY) {
  407. X
  408. X          /* have to check if this is still a liberty */
  409. X          foreachneighbor(bv, n, nn) {
  410. X              if (bv->block_id[nn] == bp->id)
  411. X            goto ok;
  412. X          } 
  413. X          /* the liberty is gone */
  414. X          --bp->nlibs;
  415. X          setremove(bp->libs, n);
  416. X        ok:;
  417. X          }
  418. X    }
  419. X    }
  420. X    else
  421. X      recycleblock(bv, bp);
  422. X}
  423. X
  424. Xundo_connect(basicview *bv, int s, block *bp, int old_undosp)
  425. X{
  426. X    block *nbp;
  427. X    int n;
  428. X    
  429. X    bv->color[s] = EMPTY;
  430. X    bv->block_id[s] = -1;
  431. X    while (bv->undosp != old_undosp) {
  432. X    nbp = bv->block_ref[pop(bv)];
  433. X    nbp->status = BLOCK_ACTIVE;
  434. X    {
  435. X        setforeach(nbp->stones, n)
  436. X          bv->block_id[n] = nbp->id;
  437. X    } 
  438. X    }
  439. X    
  440. X    recycleblock(bv, bp);
  441. X}
  442. X
  443. Xint undo(basicview *bv)
  444. X{
  445. X    int s, old_undosp, n, movetype;
  446. X    block *bp, *nbp;
  447. X    
  448. X    if (bv->undosp <= 0)
  449. X      return -1;
  450. X    
  451. X    n = pop(bv);
  452. X    movetype = n % 8;
  453. X    old_undosp = bv->undosp - 1 - (n /= 8) % 8;
  454. X    s = n / 8;
  455. X    bv->ko_spot = pop(bv);
  456. X    bv->turn--;
  457. X    bv->to_play = OTHER(bv->to_play);
  458. X    bp = bv->block_ref[bv->block_id[s]];
  459. X    
  460. X    /* uncapture */
  461. X    while (old_undosp != bv->undosp
  462. X       && bv->block_ref[top(bv)]->color == OTHER(bv->to_play))
  463. X      uncapture_block(bv, bv->block_ref[pop(bv)]);
  464. X    
  465. X    
  466. X    switch (movetype) {
  467. X      case MOVEIS_PASS:
  468. X    bv->passes--;
  469. X    return MOVEIS_PASS;
  470. X    
  471. X      case MOVEIS_NEW:
  472. X      case MOVEIS_EXTEND:
  473. X      case MOVEIS_NEW+MOVE_CAPTURES:
  474. X      case MOVEIS_EXTEND+MOVE_CAPTURES:
  475. X    undo_simple(bv, s, movetype, bp);
  476. X    break;
  477. X      case MOVEIS_CONNECT:
  478. X      case MOVEIS_CONNECT+MOVE_CAPTURES:
  479. X    undo_connect(bv, s, bp, old_undosp);
  480. X    break;
  481. X    }
  482. X    
  483. X    
  484. X    /* now update my neighbors liberties */
  485. X    {
  486. X    foreachneighbor(bv, s, n)
  487. X      if (bv->color[n] == OTHER(bv->to_play)) {
  488. X          nbp = bv->block_ref[bv->block_id[n]];
  489. X          if (!setisin(nbp->libs, s)) {
  490. X          setadd(nbp->libs, s);
  491. X          ++nbp->nlibs;
  492. X          }
  493. X      }
  494. X    } 
  495. X    
  496. X    return 0;
  497. X}
  498. SHAR_EOF
  499. if test 9845 -ne "`wc -c < 'basics.c'`"
  500. then
  501.     echo shar: error transmitting "'basics.c'" '(should have been 9845 characters)'
  502. fi
  503. fi # end of overwriting check
  504. echo shar: extracting "'godefs.h'" '(2693 characters)'
  505. if test -f 'godefs.h'
  506. then
  507.     echo shar: will not over-write existing file "'godefs.h'"
  508. else
  509. sed 's/^X//' << \SHAR_EOF > 'godefs.h'
  510. X/*
  511. X * godefs.h -- GO definitions
  512. X *
  513. X * created 7/12-90
  514. X *
  515. X * Tommy Thorn                       email: tthorn@daimi.aau.dk
  516. X * Computer Science Department       I SPEAK FOR MYSELF!
  517. X * Aarhus University 
  518. X * DENMARK
  519. X */
  520. X
  521. X#define MAX 360 /* 19^2-1 */
  522. X#ifndef SET_MAX
  523. X# define SET_MAX MAX+1
  524. X# include "set.h"
  525. X#endif
  526. X
  527. X/* boolean values */
  528. X
  529. X#define YES 1
  530. X#define NO 0
  531. X
  532. X/* color values */
  533. X
  534. X#define EMPTY 0
  535. X#define BLACK 1
  536. X#define WHITE 2
  537. X
  538. X#define OTHER(c) (3-c)
  539. X
  540. X/*
  541. X * a block is a strongly connected collection of stones of the
  542. X * same color.
  543. X */
  544. X
  545. Xtypedef struct _block {
  546. X    int id; /* unik block number */
  547. X    int status;
  548. X    int color;
  549. X    set stones, libs;
  550. X    int nlibs;
  551. X} block;
  552. X
  553. X/* block status */
  554. X
  555. X#define BLOCK_ACTIVE    0
  556. X#define BLOCK_INACTIVE    1
  557. X#define BLOCK_CAPTURED    2
  558. X
  559. X/*
  560. X * for each intersection there is an index into dir giving a zero-
  561. X * terminated list of offset. usually this is only used by
  562. X * foreachneighbor. IMPORTANT: foreach neighbor uses the locals
  563. X * defined by set_localvars(), see set.h
  564. X */
  565. X
  566. Xextern int dir[9][5];   /* dir[dirindex[s]] gives a zero terminated list */
  567. X
  568. X#define foreachneighbor(bv, s, n)                                          \
  569. X    register *_ip;                                                         \
  570. X    for (_ip = dir[bv->dirindex[s]], n = s + *_ip; *_ip; n = s + *++_ip)   
  571. X    
  572. Xtypedef struct _basicview {
  573. X    int w;                         /* board width */
  574. X    int max;                       /* w*w-1 */
  575. X    int turn;
  576. X    int to_play;                   /* next to play */
  577. X    int passes;
  578. X    int ko_spot;
  579. X    int dirindex[MAX];
  580. X    int color[MAX]; 
  581. X    int block_id[MAX];             /* which block is on this intersec. */
  582. X    block *block_ref[MAX];         /* maps block_id to a pointer */
  583. X    int next_free_id;
  584. X    int undostack[MAX*4];
  585. X    int undosp;
  586. X} basicview;
  587. X
  588. X/* top of undostack is movetype + 8 * (undoinfosize-2) + 64 * move 
  589. X * followed by old ko spot
  590. X */
  591. X
  592. X/* the error return code from play, legal and movetype */
  593. X#define ERR_OUT_OF_BOARD  -1
  594. X#define ERR_OCCUPIED      -2
  595. X#define ERR_KO_VIOLATION  -3
  596. X#define ERR_SUICIDE       -4
  597. X#define ERR_GAME_OVER     -5
  598. X
  599. X/* movetypes respective to a block */
  600. X#define MOVEIS_PASS        0
  601. X#define MOVEIS_NEW         1       /* new block */
  602. X#define MOVEIS_EXTEND      2       /* extending a block */
  603. X#define MOVEIS_CONNECT     3       /* connecting blocks */
  604. X#define MOVE_CAPTURES      4       /* is added on */
  605. X
  606. Xvoid init(basicview *, int w);
  607. Xint moveis(basicview *, int s);    /* < 0 bad, > 0 good */
  608. Xint play(basicview *, int s);      /* < 0 bad (not made), > 0 good */
  609. Xint undo(basicview *);             /* < 0 couldn't undo, undostack empty */
  610. X
  611. X#ifdef __TURBOC__
  612. Xvoid *malloc(unsigned);
  613. X#endif
  614. SHAR_EOF
  615. if test 2693 -ne "`wc -c < 'godefs.h'`"
  616. then
  617.     echo shar: error transmitting "'godefs.h'" '(should have been 2693 characters)'
  618. fi
  619. fi # end of overwriting check
  620. echo shar: extracting "'set.c'" '(1318 characters)'
  621. if test -f 'set.c'
  622. then
  623.     echo shar: will not over-write existing file "'set.c'"
  624. else
  625. sed 's/^X//' << \SHAR_EOF > 'set.c'
  626. X/*
  627. X * set.c - set rutines
  628. X *
  629. X * A set is a bitvector containing integers in the range 0..360
  630. X *
  631. X * created 18/5-90
  632. X *
  633. X * Tommy Thorn                       email: tthorn@daimi.aau.dk
  634. X * Computer Science Department       I SPEAK FOR MYSELF!
  635. X * Aarhus University 
  636. X * DENMARK
  637. X */
  638. X
  639. X#include "set.h"
  640. X
  641. X#ifdef SET_BIT
  642. Xunsigned set_bit[INTW] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512,
  643. X                1024, 2048, 4096, 8192, 16384, -32768};
  644. X#endif
  645. X
  646. Xsetinit(set s)
  647. X{
  648. X    register i;
  649. X    for (i = 0; i < SET_LEN; ++i)
  650. X      s[i] = 0;
  651. X}
  652. X
  653. Xsetunion(set sd, set s1, set s2)
  654. X{
  655. X    register i;
  656. X    
  657. X    for (i = 0; i < SET_LEN; ++i)
  658. X      sd[i] = s1[i] | s2[i];
  659. X}
  660. X
  661. Xsetinter(set sd, set s1, set s2)
  662. X{
  663. X    register i;
  664. X    
  665. X    for (i = 0; i < SET_LEN; ++i)
  666. X      sd[i] = s1[i] & s2[i];
  667. X}
  668. X
  669. Xsetdiff(set sd, set s1, set s2)
  670. X{
  671. X    register i;
  672. X    
  673. X    for (i = 0; i < SET_LEN; ++i)
  674. X      sd[i] = s1[i] & ~s2[i];
  675. X}
  676. X
  677. Xint setsize(set s)
  678. X{
  679. X    register int i, n = 0;
  680. X    register unsigned b;
  681. X    
  682. X    /* This could have been n = 0; foreach(s, i) n++
  683. X       but I've got something better ... */
  684. X    
  685. X    for (i = 0; i < SET_LEN; ++i)
  686. X      if (s[i]) {
  687. X      b = s[i];
  688. X      ++n;
  689. X      while (b = b & (b - 1)) ++n;
  690. X      }
  691. X    return n;
  692. X}
  693. X
  694. Xint setisempty(set s)
  695. X{
  696. X    register int i;
  697. X    
  698. X    for (i = 0; i < SET_LEN; ++i)
  699. X      if (s[i])
  700. X    return 0;
  701. X    return 1;
  702. X}
  703. SHAR_EOF
  704. if test 1318 -ne "`wc -c < 'set.c'`"
  705. then
  706.     echo shar: error transmitting "'set.c'" '(should have been 1318 characters)'
  707. fi
  708. fi # end of overwriting check
  709. echo shar: extracting "'set.h'" '(1565 characters)'
  710. if test -f 'set.h'
  711. then
  712.     echo shar: will not over-write existing file "'set.h'"
  713. else
  714. sed 's/^X//' << \SHAR_EOF > 'set.h'
  715. X/*
  716. X * set.h - headerfile for set rutines
  717. X *
  718. X * A set is a bitvector containing integers in the range 0..360
  719. X *
  720. X * created 18/5-90
  721. X *
  722. X * Tommy Thorn                       email: tthorn@daimi.aau.dk
  723. X * Computer Science Department       I SPEAK FOR MYSELF!
  724. X * Aarhus University 
  725. X * DENMARK
  726. X */
  727. X
  728. X#undef MAX
  729. X#define MAX 361
  730. X#define SET_LEN ((MAX-1)/8/sizeof(int))+1
  731. X#define LONGW (8*sizeof(long))
  732. X#define SET_MASK (LONGW-1)
  733. X
  734. X#define SHIFT 5
  735. X
  736. X
  737. Xtypedef unsigned long set[SET_LEN];
  738. X
  739. X#ifdef SET_BIT
  740. Xextern unsigned long set_bit[LONGW];
  741. X#endif
  742. X
  743. X#ifdef SET_BIT
  744. X#define setadd(s, e)    s[(unsigned long)e >> SHIFT] |= set_bit[e & SET_MASK]
  745. X#define setremove(s, e)    s[(unsigned long)e >> SHIFT] &= ~set_bit[e & SET_MASK]
  746. X#define setisin(s, e)    (s[(unsigned long)e >> SHIFT] & set_bit[e & SET_MASK])
  747. X#else
  748. X#define setadd(s, e)    s[(unsigned long)e >> SHIFT] |= 1 << (e & SET_MASK)
  749. X#define setremove(s, e)    s[(unsigned long)e >> SHIFT] &= ~(1 << (e & SET_MASK))
  750. X#define setisin(s, e)    (s[(unsigned long)e >> SHIFT] & (1 << (e & SET_MASK)))
  751. X#endif
  752. X
  753. X/* must be in the beginning of a block */
  754. X
  755. X#define setforeach(s, i)                                                   \
  756. X    register _j; register unsigned long _b;                                \
  757. X    for (_j = 0; _j < SET_LEN; ++_j)                       \
  758. X      if (s[_j])                               \
  759. X        for (_b = s[_j], i = _j * LONGW; _b; _b >>= 1, ++i)                \
  760. X      if (_b & 1)
  761. X
  762. Xint setinit(set s);
  763. Xint setunion(set sd, set s1, set s2);
  764. Xint setinter(set sd, set s1, set s2);
  765. Xint setdiff(set sd, set s1, set s2);
  766. Xint setsize(set s);
  767. Xint setisempty(set s);
  768. X
  769. SHAR_EOF
  770. if test 1565 -ne "`wc -c < 'set.h'`"
  771. then
  772.     echo shar: error transmitting "'set.h'" '(should have been 1565 characters)'
  773. fi
  774. fi # end of overwriting check
  775. echo shar: extracting "'test.c'" '(3562 characters)'
  776. if test -f 'test.c'
  777. then
  778.     echo shar: will not over-write existing file "'test.c'"
  779. else
  780. sed 's/^X//' << \SHAR_EOF > 'test.c'
  781. X/*
  782. X * Test BASICS -- basic view of the go board
  783. X *
  784. X * created 14/12-90
  785. X *
  786. X * Tommy Thorn                       email: tthorn@daimi.aau.dk
  787. X * Computer Science Department       I SPEAK FOR MYSELF!
  788. X * Aarhus University 
  789. X * DENMARK
  790. X */
  791. X
  792. X#include <stdio.h>
  793. X#include "godefs.h"
  794. X#include "curses.h"
  795. X#include <signal.h>
  796. X
  797. X#ifdef __TURBOC__
  798. Xunsigned _stklen = 20000;
  799. X#endif
  800. X
  801. X/* initialize the curses package and display mode */
  802. Xsetup()
  803. X{
  804. X    initscr();
  805. X    crmode();
  806. X    noecho();
  807. X    move(3,7);
  808. X}
  809. X
  810. X/* draws the current game board
  811. X   the debug package might set the high bit on some stones to indicate
  812. X   that those spots should be highlighted
  813. X*/
  814. X
  815. Xdraw(basicview *bv)
  816. X{
  817. X    register int i,j;
  818. X    int x,y;
  819. X    getyx(stdscr,y,x);
  820. X    mvaddstr(2,5,"|---------------------------------------|");
  821. X    for (i=0; i<19; ++i) {
  822. X    mvaddch(3+i,5,'|');
  823. X    for (j=0; j<19; ++j) {
  824. X        addch(' ');
  825. X        switch(bv->color[j+i*19] & 0x7F) {
  826. X          case EMPTY:
  827. X        addch('+');
  828. X        break;
  829. X          case BLACK:
  830. X        addch('@');
  831. X        break;
  832. X          case WHITE:
  833. X        addch('O');
  834. X        break;
  835. X          default: addch('!'); break; /* ERROR! */
  836. X        }
  837. X    }
  838. X    addch(' '); addch('|');
  839. X    }
  840. X    mvaddstr(3+i,5,"|---------------------------------------|");
  841. X    move(y,x);
  842. X    refresh();
  843. X}
  844. X
  845. Xstatic int lastpos = 0;
  846. X
  847. X/* relative cursor motion on a flat board with bounds-checking */
  848. Xrup(int w, int o)
  849. X{
  850. X    lastpos = (lastpos + o + w*w) % (w*w);
  851. X    move(lastpos/w+3, (lastpos%w)*2+7);
  852. X    refresh();
  853. X}
  854. X
  855. Xint fetchmove(basicview *bv)
  856. X{
  857. X    char s[80];
  858. X    
  859. X    int done = 0;
  860. X    while (!done)
  861. X      switch (getch()) {
  862. X    case 'j': rup(bv->w,  bv->w); break;
  863. X    case 'k': rup(bv->w, -bv->w); break;
  864. X    case 'h': rup(bv->w, -1); break;
  865. X    case 'l': rup(bv->w,  1); break;
  866. X      /*      case 'y': rup(bv->w, -bv->w-1); break;
  867. X          case 'u': rup(bv->w, -bv->w+1); break;
  868. X          case 'b': rup(bv->w,  bv->w-1); break;
  869. X          case 'n': rup(bv->w,  bv->w+1); break;
  870. X          */
  871. X    case 'p': return -1;
  872. X    case 'L'&0x1F: draw(bv); break;
  873. X    case '.':
  874. X    case ' ': done=1; break;
  875. X    case 'q': return -2;
  876. X    case 'b': return -3;
  877. X    case 'i':
  878. X      if (bv->block_id[lastpos] != -1) {
  879. X          sprintf(s, "Block #%d Libs %d",
  880. X              bv->block_id[lastpos],
  881. X              bv->block_ref[bv->block_id[lastpos]]->nlibs);
  882. X          comment(s);
  883. X      }
  884. X      break;
  885. X    default: beep(); break;
  886. X      }
  887. X    return lastpos;
  888. X}
  889. X
  890. Xbeep()
  891. X{
  892. X    write(2, "\007", 1);
  893. X}
  894. X
  895. X/* the opposite of setup() */
  896. Xcleanup()
  897. X{
  898. X    move(23,0);
  899. X    refresh();
  900. X    endwin();
  901. X}
  902. X
  903. Xsigexit()
  904. X{
  905. X    cleanup();
  906. X    exit(1);
  907. X}
  908. X
  909. Xmain()
  910. X{
  911. X    basicview BasicView, *bv = &BasicView;
  912. X    
  913. X    init(bv, 19);
  914. X    setup();
  915. X    draw(bv);
  916. X    do {
  917. X        doturn(bv);
  918. X    } while(bv->passes != 2);
  919. X    cleanup();
  920. X}
  921. X
  922. Xdoturn(basicview *bv)
  923. X{
  924. X    int i;
  925. X    comment("Turn %d:%s to play.",bv->turn,bv->to_play==BLACK?"BLACK":"WHITE");
  926. X    while (1) {
  927. X    i  = fetchmove(bv);
  928. X    if (i == -2)
  929. X      bv->passes = 2;
  930. X    else if (i == -3)
  931. X      undo(bv);
  932. X    else {
  933. X        switch (moveis(bv, i)) {
  934. X          case ERR_OUT_OF_BOARD:
  935. X        comment("Out of board (??)");
  936. X        continue;
  937. X          case ERR_OCCUPIED:
  938. X        comment("That spot is occupied");
  939. X        continue;
  940. X          case ERR_KO_VIOLATION:
  941. X        comment("Oh no there is a ko");
  942. X        continue;
  943. X          case ERR_SUICIDE:
  944. X        comment("Do you want to commit suicide?");
  945. X        continue;
  946. X          case ERR_GAME_OVER:
  947. X        comment("The game is over");
  948. X        continue;
  949. X        }
  950. X        play(bv, i);
  951. X    }
  952. X    break;
  953. X    }
  954. X    draw(bv);
  955. X}
  956. X
  957. X/* display a message near the bottom of the screen */
  958. Xcomment(fmt,a,b,c,d,e,f)
  959. X     char *fmt;
  960. X     int a,b,c,d,e,f;
  961. X{
  962. X    int x,y;
  963. X    getyx(stdscr,y,x);
  964. X    move(23,15);
  965. X    printw(fmt,a,b,c,d,e,f);
  966. X    clrtoeol();
  967. X    move(y,x);
  968. X    refresh();
  969. X}
  970. SHAR_EOF
  971. if test 3562 -ne "`wc -c < 'test.c'`"
  972. then
  973.     echo shar: error transmitting "'test.c'" '(should have been 3562 characters)'
  974. fi
  975. fi # end of overwriting check
  976. #    End of shell archive
  977. exit 0
  978.  
  979. --
  980. Tommy Thorn                       email: tthorn@daimi.aau.dk
  981. Computer Science Department       I SPEAK FOR MYSELF!
  982. Aarhus University 
  983. DENMARK
  984.  
  985.  
  986.